/**
 * Template
 *
 */
if(typeof (module) !="undefined"){
    module.exports = Template;

    var PrintPage = require('./PrintPage');
    var FileObj = require('./FileObj');
    var StyleProcessor = require('../common/StyleProcessor');
    var PDFDocument = require('pdfkit');
    var DS = require('../../../backServer/routes/pdf/ds/DS');
    var SubTemplateDS = require('../../../backServer/routes/pdf/ds/SubTemplateDS');
    var config = require('../../config').getConfig();
    var define = require('../../define').getDefine();
    var Serializer = require('./Serializer');
    var rpcFunc  =require('../../../backServer/routes/rpc/rpcFunc.js');
    var TVectorModel= require('../../models').TVector;
    var FColorBase = require('../color/FColorBase');
    var fs = require('fs');
    var ImageObj = require('./ImageObj');
    var async = require('async');
    var moment = require('moment');
    var archiver = require('archiver');
    var common = require('../../common');
}


function Template()
{
    this.pgs= new Array(); // 页面内容，存放各种对象
    this.ver = -1; // 版本号;
    this.colorMode = FColorBase.prototype.COLOR_MODE_RGB; // 文档颜色模式
}
// 将页面内容转换为json string（注意不转换布局）
Template.prototype.toJson = function (){

    var ret = '{';
    ret += ('"ver":'+ this.ver);
    ret +=',';
    ret += ('"colorMode":'+ this.colorMode);
    ret +=',';
    ret +='"pgs":[';
    for(var i=0;i<this.pgs.length;i++){
        if(i>0){
            ret +=',';
        }
        ret +=this.pgs[i].toJson(false);
    }
    ret += ']';


    ret +='}';
    return ret;

}
// 从json对象解析页面内容（注意不解析布局）
Template.prototype.fromJson = function(jsonObj){
    this.ver = jsonObj.ver;
    if(jsonObj.hasOwnProperty("colorMode")){
        this.colorMode = jsonObj.colorMode;
    }
    this.pgs.splice(0,this.pgs.length);
    for(var i=0;i<jsonObj.pgs.length;i++){
        var pg = new PrintPage();
        pg.fromJson(jsonObj.pgs[i],0);
        pg.index = i;
        this.pgs.push(pg);
    }

    // 给页面所有可打印对象，设置colorMode
    for(var i=0; i<this.pgs.length; i++){
        var pg = this.pgs[i];
        pg.setColorMode(this.colorMode);

    }

}


// 简化数据
// 参数：common.PAGE_REPLACEABLE_INFO_STRUCT 的数组
Template.prototype.simplifyReplaceGroup = function(serialCallback){
    // 将所有页组成tasks，串行调用
    var THIS = this;
    var tasks = new Array();
    for (var i=0; i < this.pgs.length; i++) {
        tasks.push(function (index) {
            return function (callback) {
                // 简化数据
                var pg = THIS.pgs[index];
                pg.simplifyReplaceGroup(callback);
            }
        }(i) );
    }
    // 串行处理，所有文档生成完成后执行回调
    async.series(tasks, function (err, replaceGroups) {
        var infos = new Array();
        for(var i=0;i<replaceGroups.length;i++){
            var rInfo = new common.PAGE_REPLACEABLE_INFO_STRUCT();
            rInfo.index = i;
            rInfo.rootReplaceGroup = replaceGroups[i];
            infos.push(rInfo);
        }

        serialCallback(null, infos);
    });
}

/**
 * 取得模板中所有文字的轮廓 的di,
 * 返回：数组
 */
Template.prototype.getTextContourDis = function(){
    // 找到每页中的不同类型的SubTemplateObj对象
    var ret = new Array();
    for(var i=0;i<this.pgs.length;i++){
        var subRet = this.pgs[i].getTextContourDis();
        for(var j=0;j<subRet.length;j++){
            ret.push(subRet[j]);
        }
    }
    return ret;
}
/**
 * 设置所有文字的轮廓
 * 参数：vectors： TVectorModel类型的数组
 */
Template.prototype.setTextContour = function(vectors){
    for(var i=0;i<this.pgs.length;i++){
        this.pgs[i].setTextContour(vectors);
    }
}
/**
 * 打包PDF
 * @param dir        PDF所在的文件夹，例如：public/pdf/2015_9_8_12_32_24
 * @param zipPath        PDF所在的文件夹，例如：public/pdf/2015_9_8_12_32_24.zip
 * @param packEndCallback  创建pdf成功后的回调
 */
Template.prototype.packPdf = function(dir,zipPath, packEndCallback){
    var output = fs.createWriteStream(zipPath);
    var archive = archiver('zip');

    output.on('close', function() {
        console.log(archive.pointer() + ' total bytes');
        console.log('archiver has been finalized and the output file descriptor has closed.');
        packEndCallback();
    });

    archive.on('error', function(err) {
        throw err;
    });

    archive.pipe(output);

    archive.bulk([
        { expand: true, cwd:dir+ '/', src: ['*.pdf'] }
    ]);

    archive.finalize();
}
/**
 * 创建PDF
 * @param config        配置信息，Object结构
 * @param makeEndCallback  创建pdf成功后的回调
 */
Template.prototype.makePdf = function(config, makeEndCallback){

    var THIS = this;

    // 生成PDF的文件夹
    var dir = 'public/pdf';
    var m = moment(new Date());
    var randomDir =m.format('YYYY_MM_DD_')+m.format('HH_mm_ss_SSS_')+Math.floor(Math.random()*100000);
    dir  =dir +'/'+randomDir;
    var zipPath = dir +".zip";
    fs.mkdir(dir+'/', 0777, function(err){
        // 取得所有的文字的轮廓（根据文字di取得pc）
        THIS.getTextContourFromDB(function(){
            // 取得复杂图形对象的轮廓（简单图形对象无di，复杂图形对象有di）
            THIS.getGraphConntourFromDB(function(){

                // 处理图片特效等各种效果
                THIS.processImage(function(paths){
                    // 创建pdf
                    THIS.serialMakePdf(dir, function(){
                        // pdf 打包
                        THIS.packPdf(dir,zipPath, function(){
                            // 删除临时图片
                            THIS.deleteImg(paths,function(){
                                makeEndCallback(dir, zipPath);
                            });
                        });
                    });
                });
            });
        });
    });

}

// 利用series来生成所有页
// 参数：dir ，生成目录，相对于本工程，无后斜杠，例如：public/pdf
Template.prototype.serialMakePdf = function(dir, serialCallback){
    // 将所有页组成tasks，串行调用
    var THIS = this;
    var tasks = new Array();
    for (var j = 0; j < this.pgs.length; j++) {
        tasks.push(function (m, index) {
            return function (callback) {
                THIS.pdf(dir, m, index, callback);
            }
        }(this.pgs[j],j) );
    }
    // 串行处理，所有文档生成完成后执行回调
    async.series(tasks, function (err, result) {
        serialCallback();
    });

}
//生成pdf文档
// 参数：dir ，生成目录，相对于本工程，无后斜杠，例如：public/pdf
Template.prototype.pdf = function(dir, page,i, callback){

    // 在obj之间传递的参数
    var info = {};
    info.docOriginX = 0;
    info.docOriginY = 0;
    info.clip = false;
    info.w = page.w;
    info.h = page.h;

    // 文档信息选项
    var options = {};
    options.size = [page.w,page.h];

    var doc = new PDFDocument(options);
	//----------------------------start----------------------------------------------
	// 浏览器中的lineWidth、lineCap、lineJoin、miterLimit都是属性，不是函数
	// 为了共用同一套代码，封装以下函数：
    doc.lineWidthFunc = function(width) {    return this.lineWidth(width); }
    doc.lineCapFunc = function(cap)     {    return this.lineCap(cap);     }
    doc.lineJoinFunc = function(join)   {    return this.lineJoin(join);   }
    doc.miterLimitFunc = function(limit){    return this.miterLimit(limit);}
	//-----------------------------end-----------------------------------------------


    doc.info['Title'] = 'F';
    doc.info['Author'] = 'F';
    var s = fs.createWriteStream(dir+'/output'+i+'.pdf').on('close', function () {
        callback();
    });
    doc.pipe(s);
    page.addToPdf(doc, info);
    doc.end();
}
/**
 *  二维数组转一维数组
 *  参数：
 *         result：二维数组
 */
Template.prototype.change2DArr = function(result){
    var paths = [];
    for(var i=0;i<result.length;i++){
        var oneArr = result[i];
        if(oneArr){
            for(var j=0;j<oneArr.length;j++){
                if(oneArr[j])
                    paths.push(oneArr[j]);
            }
        };
    }
    return paths;
}

/**
 *  处理图片（利用串行操作处理图片的特效以及阴影效果，并替换ImageObj的fp属性）
 *  参数：
 *          endCallback：处理完成后的回调，必须传入含有特效的临时图片的地址的数组
 */
Template.prototype.processImage = function(endCallback){
    var THIS = this;

    // 图片替换为高精度图
    THIS.processBigImage();

    // 处理图片特效
    async.series([
        function(callback){
            THIS.processImageFilter(function(paths){
                callback(null, paths);
            })
        }
        ,
        function(callback){
            THIS.processImageShadow(function(paths){
                callback(null, paths);
            })
        }
    ],function(err,result){
        var paths = Template.prototype.change2DArr(result);
        endCallback(paths);
    })
}

/**
 *  图片url替换为大图路径
 */
Template.prototype.processBigImage= function(){
    // 取得所有图片对象
    var imageObjs = new Array();
    for(var i=0;i<this.pgs.length;i++){
        var o= this.pgs[i].root.getImageObjs();
        for(var n=0;n< o.length;n++){
            imageObjs.push(o[n]);
        }

    }

    for(var i=0;i<imageObjs.length;i++){
        var img = imageObjs[i];
        img.fp = config.getOriginImageUrl(img.fp);
    }
}

/**
 *  处理特效图片（生成特效图片，并替换ImageObj的fp属性）
 *  参数：
 *          endCallback：处理完成后的回调，必须传入含有特效的临时图片的地址的数组
 */
Template.prototype.processImageFilter= function(endCallback){
    // 取得所有图片对象
    var imageObjs = new Array();
    for(var i=0;i<this.pgs.length;i++){
        var o= this.pgs[i].root.getImageObjs();
        for(var n=0;n< o.length;n++){
            imageObjs.push(o[n]);
        }

    }
    if(imageObjs.length==0){
        // 没有图片直接回调
        endCallback();
    }else{
        // 处理所有图片的路径
        var tasks = new Array();

        for(var k=0;k<imageObjs.length;k++){
            tasks.push(function(m){
                return function(callback){
                    StyleProcessor.prototype.processImageFilter(m,function(path){
                        callback(null,path);
                    })
                }
            }(imageObjs[k])
            );
        }
        // 并行处理，所有图片处理完成后执行回调
        async.parallel(tasks,function(err,result){
            var paths = [];
            if(result && result.length>0){
                for(var i=0;i<result.length;i++){
                    paths.push(result[i]);
                }
            }
            endCallback(paths);
        })
    }
}
/**
 *  处理阴影图片（生成图片阴影效果o，并替换ShadowObj的fp属性）
 *  参数：
 *          endCallback：处理完成后的回调，必须传入含有特效的临时图片的地址的数组
 */
Template.prototype.processImageShadow= function(endCallback){
    // 取得所有图片对象
    var THIS = this
    var imageObjs = new Array();
    for(var i=0;i<this.pgs.length;i++){
        var o= this.pgs[i].root.getImageObjs();
        for(var n=0;n< o.length;n++){
            imageObjs.push(o[n]);
        }
    }
    if(imageObjs.length==0){
        // 没有图片直接回调
        endCallback();
    }else{
        // 处理所有图片的路径
        var tasks = new Array();
       for(var k=0;k<imageObjs.length;k++){
            tasks.push(function(m){
                return function(callback){
                    StyleProcessor.prototype.createShadowImageObj(m,function(path,newImage){
                        var para = {};
                        para.path = path;
                        para.newImage = newImage
                        callback(null,para);
                    })
                }
            }(imageObjs[k])
            );
        }
        // 并行处理，所有图片处理完成后执行回调
        async.parallel(tasks,function(err,result){
            var paths = [];
            if(result && result.length>0){
                for(var i=0;i<result.length;i++){
                    var para = result[i];
                    if(para.path){
                        paths.push(para.path);
                    }
                    if(para.newImage){
                        //将生成的阴影图片对象插入到result[i].newImage的下面
                        THIS.insertShadowImgToPgs(para.newImage);
                    }
                }
            }
            endCallback(paths);
        })
    }
}

/**
 *  把newImage插入到pgs中from的下方
 *  参数：
 *          shadowImage：图片阴影对象
 */
Template.prototype.insertShadowImgToPgs = function(shadowImage){

    for(var i=0;i<this.pgs.length;i++){
        var ret =this.pgs[i].root.insertShadowImgObj(shadowImage);
        if(ret)
            return ret;
    }
}
/**
 * 取得复杂图形对象的轮廓（简单图形对象无di，复杂图形对象有di）
 */
Template.prototype.getGraphConntourFromDB = function(callback){
    // 取得所有包含di的图形对象
    var diGraphObjs = new Array();
    var dis = new Array();
    for(var i=0;i<this.pgs.length;i++){
        var o =  this.pgs[i].root.getGraphObjs(true);
        for(var n=0;n< o.length;n++){
            diGraphObjs.push(o[n]);
            dis.push(o[n].di);
        }
    }

    if(dis.length==0){
        callback();
    }else{
        // 取文字轮廓(统一取，统一设，节省开销
        TVectorModel.where('id').in(dis).exec(function (error, items) {
            if(error) {
                console.log(error);
            }else if(items&& items.length>0){
                for(var k=0;k<diGraphObjs.length;k++){
                    var to = diGraphObjs[k];
                    // 找到未访问过的
                    if(to && !to.hasOwnProperty('visit') ){
                        for(var m=0; m<items.length; m++){
                            var oneItem = items[m];
                            if(oneItem && oneItem.id.equals(to.di) ){ // 一个文字轮廓可能设置到多个TextObj对象上
                                to.visit = true;        // 设置访问标记
                                to.cp.fromJson(JSON.parse(oneItem.content));
                            }

                        }

                    }
                }
            }
            callback();
        });
    }

}
/**
 *  取得所有的文字的轮廓（根据文字di取得pc）
 */
Template.prototype.getTextContourFromDB = function(callback){

    // 取得所有文字对象
    var textObjs = new Array();
    var dis = new Array();
    for(var i=0;i<this.pgs.length;i++){
        var o =  this.pgs[i].getTextObjs(true);
        for(var n=0;n< o.length;n++){
            textObjs.push(o[n]);
            dis.push(o[n].di);
        }
    }

    if(dis.length==0){
        callback();
    }else{
        // 取文字轮廓(统一取，统一设，节省开销
        TVectorModel.where('id').in(dis).exec(function (error, items) {
            if(error) {
                console.log(error);
            }else if(items&& items.length>0){
                for(var k=0;k<textObjs.length;k++){
                    var to = textObjs[k];
                    // 找到未访问过的
                    if(to && !to.hasOwnProperty('visit') ){
                        for(var m=0; m<items.length; m++){
                            var oneItem = items[m];
                            if(oneItem && oneItem.id.equals(to.di) ){ // 一个文字轮廓可能设置到多个TextObj对象上
                                to.visit = true;        // 设置访问标记
                                to.pc.updateCharPtsFromSrv(JSON.parse(oneItem.content));
                                to.adjustAllChar();
//                                to.pc.adjustByCharPts(JSON.parse(oneItem.content), true);
//                                to.pc.fromJson(JSON.parse(oneItem.content));
                            }

                        }

                    }
                }
            }
            callback();
        });
    }


}
/**
 * 创建空白数据源
 * 返回  DS  （如果不含有SubTemplateObj对象，则返回null）
 */
Template.prototype.newEmptyDS = function(){
    // 找到每页中的不同类型的SubTemplateObj对象
    var subTemObjs = new Array();
    for(var i=0;i<this.pgs.length;i++){
        var subRet = this.pgs[i].getSubTemplateObj();
        for(var j=0;j<subRet.length;j++){
            subTemObjs.push(subRet[j]);
        }
    }
    // 不含有SubTemplateObj对象
    if(subTemObjs.length==0){
        return null;
    }

    // 利用map进行分类
    var map = {};
    for(var i=0;i<subTemObjs.length;i++){
        var s = subTemObjs[i];
        var stds = s.newEmptySubTemplateDS();
        if(!map.hasOwnProperty(stds.tn)){
            map[stds.tn] = new Array();
        }
        map[stds.tn].push(stds);
    }

    // 遍历map创建DS
    var ret = new DS();
    for ( var p in map ){ // 方法
        if ( typeof ( map[p]) == "function" ){

        } else {
            // p 为属性名称，map[p]为对应属性的值
            ret.map = map;
        }
    }

    return ret;
}

/**
 * 给对象绑定数据源
 * 参数： ds：数据源对象DS
 */
Template.prototype.bindDS = function(ds){
    // 遍历ds的map的key，根据key取得版面中对象的SubTemplateObj对象
    for ( var p in ds.map ){ // 方法
        if ( typeof ( ds.map[p]) == "function" ){

        } else {
            var value = ds.map[p];
            var stos = new Array();
            for(var i=0;i<this.pgs.length;i++){
                var subRet = this.pgs[i].getSubTemplateObj(p);
                for(var m=0;m<subRet.length;m++){
                    stos.push(subRet[m]);
                }
            }

            // 将map的key对应的value设置到SubTemplateObj对象中去
            for(var w=0;w<stos.length;w++){
                if(w>= value.length)    continue;

                var d = value[w];
                var o = stos[w];
                o.bindData(d);

            }
        }
    }


    return;
    // 找到每页中的不同类型的SubTemplateObj对象的子对象
    var subTemObjs = new Array();
    for(var i=0;i<this.pgs.length;i++){
        var subRet = this.pgs[i].getSubTemplateObj();
        for(var j=0;j<subRet.length;j++){
            var subOfDS = subRet[j].getSubObjOfDS();
            for(var k=0;k<subOfDS.length;k++){
                subTemObjs.push(subOfDS[k]);
            }

        }
    }


    // 不含有SubTemplateObj的子对象
    if(subTemObjs.length==0)   return null;


    // 取得ItemDS
    var idss = ds.getItemDS();

    // 按顺序赋值
    if(idss.length != subTemObjs.length)  return null;

    for(var i=0;i<subTemObjs.length;i++){
        var subObj = subTemObjs[i];
        var ids = idss[i];
        if(subObj.ct == Serializer.prototype.CLASS_TYPE_IMAGEOBJ){
            subObj.fp = ids.value;
        }else if(subObj.ct == Serializer.prototype.CLASS_TYPE_TEXTOBJ){
            subObj.te = ids.value;
            subObj.di = ids.di;
        }
    }
}

//删除生成的临时图片
// 参数：
//      paths:数组类型，存放图片路径
//      callback:删除后的回调
Template.prototype.deleteImg = function(paths,callbcak){
    if(paths==null || paths.length==0){
        callbcak();
        return;
    }
    // 删除图片
    for(var i=0; i<paths.length; i++){
        fs.unlink(paths[i]);
        console.log(paths[i])
    }

    callbcak();
}
